package com.example.hutool;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.io.FileUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import cn.hutool.crypto.symmetric.AES;

import java.io.File;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;

/**
 * SecureUtil
 * 安全相关工具类
 * 加密分为三种：
 * 1、对称加密（symmetric），例如：AES、DES等
 * 2、非对称加密（asymmetric），例如：RSA、DSA等
 * 3、摘要加密（digest），例如：MD5、SHA-1、SHA-256、HMAC等
 *
 * @author 江黎
 * @since 2022-11-05
 */
public class 加解密工具类 {

    public static void main(String[] args) {
        // md5
        String md5 = SecureUtil.md5("hello");
        System.out.println(md5);
        // md5的参数可以是字符串也可以是文件
        File file = new File("C:\\Users\\jiangli\\Desktop\\study.txt");
        md5 = SecureUtil.md5(file);
        System.out.println(md5);

        // sha256
        System.out.println(SecureUtil.sha256("hello"));


        // AES 加密
        byte[] key = "qwertyuiopasdfgh".getBytes();
        AES aes = SecureUtil.aes(key);
        File srcFile = new File("C:\\Users\\jiangli\\Desktop\\文件传输.postman_collection.json");
        File cipherFile = new File("C:\\Users\\jiangli\\Desktop\\cipherFile.txt");
        byte[] srcBytes = FileUtil.readBytes(srcFile);
        byte[] encryptBytes = aes.encrypt(srcBytes);
        FileUtil.writeBytes(encryptBytes, cipherFile);
        // 解密
        File destFile = new File("C:\\Users\\jiangli\\Desktop\\destFile.txt");
        byte[] cipherFileBytes = FileUtil.readBytes(cipherFile);
        byte[] decryptBytes = aes.decrypt(cipherFileBytes);
        FileUtil.writeBytes(decryptBytes, destFile);

        byte[] admins = aes.encrypt("admin");
        System.out.println(admins);
        byte[] decrypt = aes.decrypt(admins);
        System.out.println(new String(decrypt));


        // RSA 生成密钥对http://web.chacuo.net/netrsakeypair
        // 生成密钥对
        KeyPair kyePair = SecureUtil.generateKeyPair("RSA");
        // 获取公钥
        PublicKey publicKeyPair = kyePair.getPublic();
        // 获取私钥
        PrivateKey privateKeyPair = kyePair.getPrivate();
        byte[] publicKeyBytes = publicKeyPair.getEncoded();
        byte[] privateKeyBytes = privateKeyPair.getEncoded();
        // 使用Base64加密转换为字符串保存起来
        String publicKey = Base64.encode(publicKeyBytes);
        String privateKey = Base64.encode(privateKeyBytes);
        System.out.println("公钥：" + publicKey);
        System.out.println("私钥：" + privateKey);

        // 根据保存的字符串将公钥私钥还原成具体的公钥类和私钥类
        byte[] publicKeyDecode = Base64.decode(publicKey);
        PublicKey publicKey1 = SecureUtil.generatePublicKey("RSA", publicKeyDecode);
        byte[] privateKeyDecode = Base64.decode(privateKey);
        PrivateKey privateKey1 = SecureUtil.generatePrivateKey("RSA", privateKeyDecode);
        // 根据公钥私钥类生成对应的RSA对象
        RSA rsaPublic = new RSA(null, publicKey1);
        RSA rsaPrivate = new RSA(privateKey1, null);

        String data = "白日依山尽，黄河入海流。";
        // 使用公钥加密
        String encryptBase64 = rsaPublic.encryptBase64(data, StandardCharsets.UTF_8, KeyType.PublicKey);
        System.out.println("密文：" + encryptBase64);
        // 使用私钥解密
        String decryptStr = rsaPrivate.decryptStr(encryptBase64, KeyType.PrivateKey);
        System.out.println("明文：" + decryptStr);

    }

}
